#include <iostream>
#include "Thread.hpp"
#include "LockGUard.hpp"
using namespace ThreadNodule;

class ThreadData
{
public:
    ThreadData(int &tickets, string &name, pthread_mutex_t &mutex) : _tickets(tickets), _name(name), _total(0), _mutex(mutex)
    {
    }
    ~ThreadData()
    {
    }

public:
    int &_tickets; // 所有的线程都会引用一个全局的数
    string _name;
    int _total;
    pthread_mutex_t _mutex;
};

// pthread_mutex_t gmutex=PTHREAD_MUTEX_INITIALIZER;

int g_tickets = 1000; // 共享资源

// void route(ThreadData *td)
// {
//     //加锁
//     while (true)
//     {
//         //pthread_mutex_lock(&gmutex);//加锁
//         pthread_mutex_lock(&td->_mutex);
//         if (td->_tickets > 0)//1
//         {
//             usleep(1000);
//             printf("%s is running,get tickets: %d\n",td->_name.c_str(),td->_tickets);//2
//             td->_tickets--;//3
//             //pthread_mutex_unlock(&gmutex);//解锁
//             pthread_mutex_unlock(&td->_mutex);
//             td->_total++;
//         }
//         else
//         {
//             //pthread_mutex_unlock(&gmutex);//解锁
//             pthread_mutex_unlock(&td->_mutex);
//             break;
//         }
//     }
// }

void route(ThreadData *td)
{
    // 加锁
    while (true)
    {
        LockGuard guard(&td->_mutex);//临时对象 ，RAII风格的
        if (td->_tickets > 0) // 1
        {
            usleep(1000);
            printf("%s is running,get tickets: %d\n", td->_name.c_str(), td->_tickets); // 2
            td->_tickets--;                                                             // 3
            td->_total++;
        }
        else
        {
            break;
        }
    }
}

const int num = 4;
int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);

    vector<Thread<ThreadData *>> threads;
    vector<ThreadData *> datas;
    // 创建一批进程
    for (int i = 0; i < num; i++)
    {
        string name = "thread-" + to_string(i + 1);
        ThreadData *td = new ThreadData(g_tickets, name, mutex);
        threads.emplace_back(route, td, name);
        datas.emplace_back(td);
    }

    // 启动一批进程

    for (auto &thread : threads)
    {
        thread.Start();
    }

    // 等待一批进程
    for (auto &thread : threads)
    {
        thread.Join();
        // cout << "wait thread done,name:" << thread.name() << endl;
    }

    sleep(1);
    // 输出统计数据
    for (auto &data : datas)
    {
        cout << data->_name << " : " << data->_total << endl;

        delete data;
    }
    pthread_mutex_destroy(&mutex);

    // Thread<int> td(print,10);

    // td.Start();

    // td.Join();
    return 0;
}